package com.xiake.zojcodesandbox.utils;

import cn.hutool.core.util.StrUtil;
import com.xiake.zojcodesandbox.enums.ExitStatusEnum;
import com.xiake.zojcodesandbox.model.ExecuteMessage;
import org.springframework.util.StopWatch;

import java.io.*;

public class ProcessUtils {
    /**
     * 执行进程并获取信息
     * @param process
     * @param cmdName
     * @return
     */
    public static ExecuteMessage runProcessAndGetMessage( Process process,String cmdName){
        ExecuteMessage executeMessage = new ExecuteMessage();

        try{
            int ExitValue = process.waitFor(); //等待编译完成

            if(ExitValue==0){
                executeMessage.setExitValue(ExitStatusEnum.SUCCESS.getExitValue());
                //编译或者执行成功，才计时
                StopWatch stopWatch = new StopWatch();
                stopWatch.start();
                System.out.println(cmdName+"成功");
                //分批次获取正常编译信息
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String compileOutputLine;
                StringBuilder messageBuilder=new StringBuilder();
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    messageBuilder.append(compileOutputLine);
                }
                executeMessage.setMessage(messageBuilder.toString());
                stopWatch.stop();
                executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
            }else{
                System.out.println(cmdName+"失败,错误码为："+ExitValue);
                if(cmdName.equals("编译")){
                    executeMessage.setExitValue(ExitStatusEnum.COMPILE_ERROR.getExitValue());
                }else{
                    executeMessage.setExitValue(ExitStatusEnum.RUNTIME_ERROR.getExitValue());
                }

                //编译失败，返回正常编译错误信息
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String compileOutputLine;
                StringBuilder messageBuilder=new StringBuilder();
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    messageBuilder=messageBuilder.append(compileOutputLine);
                }
                messageBuilder.append(messageBuilder.toString());
                //获取错误流，返回错误编译信息
                BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String errorLine;
                StringBuilder errorBuilder = new StringBuilder();
                while ((errorLine = errorStream.readLine()) != null) {
                    errorBuilder.append(errorLine);
                }
                //编译或运行失败，返回错误信息
                executeMessage.setErrorMessage(errorBuilder.toString());
            }

        }
        catch(Exception e){
            e.printStackTrace();
        }
       return executeMessage;
    }

    /**
     * 执行交互式进程并获取信息
     *
     * @param runProcess
     * @param args
     * @return
     */
    public static ExecuteMessage runInteractProcessAndGetMessage(Process runProcess, String args) {
        ExecuteMessage executeMessage = new ExecuteMessage();

        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            // 向控制台输入程序
            OutputStream outputStream = runProcess.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            String[] s = args.split(" ");
            String join = StrUtil.join("\n", s) + "\n";
            outputStreamWriter.write(join);
            // 相当于按了回车，执行输入的发送
            outputStreamWriter.flush();

            // 分批获取进程的正常输出
            InputStream inputStream = runProcess.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            // 逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            executeMessage.setMessage(compileOutputStringBuilder.toString());
            // 记得资源的释放，否则会卡死
            outputStreamWriter.close();
            outputStream.close();
            inputStream.close();
            runProcess.destroy();
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return executeMessage;
    }
}
